<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>js函数之call,apply,bind</title>
</head>
<body>
  <ul>
    <li>使用call,apply改变this指针的指向，将this指向当前传入的对象，且函数会立即执行</li>
    <li>call与apply的区别：call可传入多个参数，apply只能传入数组</li>
    <li>使用bind也能改变this指针的指向，将this指向当前传入的对象，但函数不会立即执行，同时返回一个函数</li>
    <li>使用bind传参有两种方式：定义时传参(优先)或调用时传参</li>
    <li>使用bind常用于处理事件回调从外面传入参数</li>
  </ul>
  <button name="vue">Vue学习</button>
  <button name="react">React学习</button>
  <script>
    const user = {
      name: 'Miracle'
    }
    function Person(url, skills) {
      console.log(this.name, url, skills)
    }
    Person.call(user, 'https://github.com/miracle-git', ['js', 'es', 'ts'])
    Person.apply(user, ['https://github.com/miracle-git', ['js', 'es', 'ts']])
    const func1 = Person.bind(user)
    func1('https://github.com/miracle-git', ['js', 'es', 'ts'])
    const func2 = Person.bind(user, 'https://github.com/miracle-git', ['js', 'es', 'ts'])
    func2()
    // 应用
    function show() {
      alert(this.innerHTML)
    }
    const buttons = document.querySelectorAll('button')
    buttons.forEach(item => {
      item.addEventListener('click', (e) => {
        show.call(e.target)
        // show.apply(e.target)
      })
    })
    // 获取数组最大值
    console.log(Math.max(1, 3, 2, 6, 4, 5))                // 6
    console.log(Math.max(...[1, 3, 2, 6, 4, 5]))           // 6
    console.log(Math.max.apply(Math, [1, 3, 2, 6, 4, 5]))  // 6
    // bind处理事件回调
    document.querySelector('[name="vue"]').addEventListener('click', function(e) {
      console.log(this)                                    // {name: "Miracle"}
      alert(`${this.name}-${e.target.innerHTML}`)
    }.bind(user))
  </script>
</body>
</html>